package com.arsl.client;

import com.arsl.client.event.KillContainerEvent;
import com.arsl.client.event.KillContainerEventHandler;
import com.arsl.client.event.LoginEvent;
import com.arsl.client.event.LoginEventHandler;
import com.arsl.client.event.ShowViewEvent;
import com.arsl.client.event.ShowViewEventHandler;
import com.arsl.client.presenter.AddContentPresenter;
import com.arsl.client.presenter.CreateArPagePresenter;
import com.arsl.client.presenter.ManagePaperPresenter;
import com.arsl.client.presenter.PageTaggerPresenter;
import com.arsl.client.presenter.SignInPanelPresenter;
import com.arsl.client.view.AddContentView;
import com.arsl.client.view.AnalyticsView;
import com.arsl.client.view.Banner;
import com.arsl.client.view.CreateARPageView;
import com.arsl.client.view.ManagePaperView;
import com.arsl.client.view.Menu;
import com.arsl.client.view.PageSelectorPanel;
import com.arsl.client.view.PageTagger;
import com.arsl.client.view.SignInPanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;

public class AppController {

	private static final String CONTENT_PANEL = "contentPanel";
	private static final String LOGIN_PANEL = "loginPanel";
	private static final String HEAD = "head";
	private static final String MENUBAR = "menu";

	public final HandlerManager eventBus;
	public final PaperaziServiceAsync rpcService;

	private int currentArPageId; // the id of the ar page currently working on
	protected int currentPaperId;

	private HasWidgets contentPanel;

	private RootPanel rootPanel;
	PopupPanel popupPanel;

	private Banner banner;

	public AppController(PaperaziServiceAsync rpcService,
			HandlerManager eventBus, RootPanel rootPanel) {
		this.eventBus = eventBus;
		this.rpcService = rpcService;
		this.rootPanel = rootPanel;
		GlobalInfo.eventBus = eventBus;
		GlobalInfo.rpcService = rpcService;
		this.contentPanel = rootPanel.get(CONTENT_PANEL);
		banner = new Banner();
		banner.setEventBus(eventBus);

		rootPanel.get(HEAD).add(banner);

		popupPanel = new PopupPanel();
		popupPanel.setGlassEnabled(true);

		bind();

	}

	private void bind() {
		// History.addValueChangeHandler(this);

		eventBus.addHandler(ShowViewEvent.TYPE, new ShowViewEventHandler() {

			@Override
			public void onShowViewEvent(ShowViewEvent event) {
				if (ShowViewEvent.VIEW_CREATE_AR_PAGE.equals(event
						.getArg(ShowViewEvent.VIEW_ARG))) {
					showCreateArPage();
				} else if (ShowViewEvent.VIEW_MANAGE_PAPER.equals(event
						.getArg(ShowViewEvent.VIEW_ARG))) {
					showManagePaper();
				} else if (ShowViewEvent.VIEW_ANALYTICS.equals(event
						.getArg(ShowViewEvent.VIEW_ARG))) {
					showAnalytics();
				} else if (ShowViewEvent.VIEW_PAGE_TAGGER.equals(event
						.getArg(ShowViewEvent.VIEW_ARG))) {
					currentArPageId = Integer.parseInt(event
							.getArg(ShowViewEvent.ARG_ARPAGEID));
					currentPaperId = Integer.parseInt(event
							.getArg(ShowViewEvent.ARG_PAPERID));
					showPageTagger();
				} else if (ShowViewEvent.VIEW_ADD_CONTENT.equals(event
						.getArg(ShowViewEvent.VIEW_ARG))) {
					AddContentView view = new AddContentView();
					view.setPublisherId(GlobalInfo.publisherId);

					AddContentPresenter presenter = new AddContentPresenter(
							eventBus, rpcService, view);
					presenter.go(popupPanel);
					popupPanel.center();
				} else if (ShowViewEvent.VIEW_PAGESELECTOR_PANEL.equals(event
						.getArg(ShowViewEvent.VIEW_ARG))) {
					PageSelectorPanel psPanel = new PageSelectorPanel();
					psPanel.setRpcService(rpcService);
					psPanel.setEventBus(eventBus);
					psPanel.setContainer(popupPanel);
					popupPanel.clear();
					popupPanel.add(psPanel);
					popupPanel.center();
				}
			}
		});

		eventBus.addHandler(LoginEvent.TYPE, new LoginEventHandler() {

			@Override
			public void onLoginEvent(LoginEvent loginEvent) {
				if (LoginEvent.LOGIN.equals(loginEvent.getEventType())) {
					doLogIn(loginEvent.getUserId(), loginEvent.getEmail(),
							loginEvent.getPublisherId());
				} else {
					doLogOut();
				}
			}
		});

		eventBus.addHandler(KillContainerEvent.TYPE,
				new KillContainerEventHandler() {

					@Override
					public void onKillContainerEvent(KillContainerEvent event) {
						HasWidgets container = event.getContainer();
						if (container instanceof PopupPanel) {
							((PopupPanel) container).hide();
						}
					}
				});
	}

	protected void showAnalytics() {
		GWT.runAsync(new RunAsyncCallback() {

			public void onFailure(Throwable caught) {
			}

			public void onSuccess() {
				AnalyticsView analyticsView = new AnalyticsView();
				rootPanel.get(CONTENT_PANEL).clear();
				contentPanel.clear();
				contentPanel.add(analyticsView);
			}
		});

	}

	protected void doLogIn(int userId, String email, int publisherId) {
		GlobalInfo.userId = userId;
		GlobalInfo.email = email;
		GlobalInfo.publisherId = publisherId;
		GlobalInfo.isLoggedIn = true;
		showLoggedInView();

	}

	private void showLoggedInView() {
		banner.setLoggedIn(true);
		banner.setUserName(GlobalInfo.email);
		showLoggedInMenu();

		ShowViewEvent ev = new ShowViewEvent();
		ev.setArg(ShowViewEvent.VIEW_ARG, ShowViewEvent.VIEW_CREATE_AR_PAGE);
		eventBus.fireEvent(ev);

	}

	private void showLoggedInMenu() {

		Menu menu = new Menu();
		menu.setEventBus(eventBus);
		rootPanel.get(CONTENT_PANEL).clear();
		rootPanel.get(MENUBAR).clear();
		rootPanel.get(MENUBAR).add(menu);

	}

	protected void doLogOut() {
		GlobalInfo.clearAll();
		showLoggedOutView();
	}

	public void showLoggedOutView() {
		SignInPanel signInPanel = new SignInPanel();
		SignInPanelPresenter presenter = new SignInPanelPresenter(rpcService,
				eventBus, signInPanel);
		signInPanel.setPresenter(presenter);
		banner.setLoggedIn(false);
		rootPanel.get(CONTENT_PANEL).clear();
		presenter.go(rootPanel.get(CONTENT_PANEL));

		HorizontalPanel panel = new HorizontalPanel();
		rootPanel.get(MENUBAR).clear();
		rootPanel.get(MENUBAR).add(panel);
	}

	public void showCreateArPage() {
		GWT.runAsync(new RunAsyncCallback() {

			public void onFailure(Throwable caught) {
			}

			public void onSuccess() {
				CreateARPageView createARPageView = new CreateARPageView();
				createARPageView.setRpcService(rpcService);
				rootPanel.get(CONTENT_PANEL).clear();
				new CreateArPagePresenter(rpcService, eventBus,
						createARPageView).go(contentPanel);
			}
		});
	}

	public void showPageTagger() {
		GWT.runAsync(new RunAsyncCallback() {
			public void onFailure(Throwable caught) {
			}

			public void onSuccess() {
				PageTagger tagger = new PageTagger();
				tagger.setArPageId(currentArPageId);
				tagger.setPaperId(currentPaperId);
				new PageTaggerPresenter(rpcService, eventBus, tagger)
						.go(contentPanel);
			}
		});

	}

	public void showManagePaper() {
		GWT.runAsync(new RunAsyncCallback() {
			public void onFailure(Throwable caught) {
			}

			public void onSuccess() {
				ManagePaperView view = new ManagePaperView();
				new ManagePaperPresenter(view).go(contentPanel);
			}
		});

	}

}
